package com.hardydou.framework.humanskill;

import com.hardydou.common.controller.BaseController;
import com.hardydou.framework.exception.LoginException;
import com.hardydou.framework.humanskill.skill.ImageSkill;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.filter.OncePerRequestFilter;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

/**
 * @author ：hardy
 * @description：人类验证
 * @date ：Created in 2020/6/13
 * @Copyright ：Hardydou.com
 */
@Configuration
public class HumanSkillConfig {
    private final static String LOGIN_URI = "/login";
    public final static String REQ_PATH = "/humanskill";
    private final static String PARAM = "hs-token";
    private final static String KEY = "skill";

    @ApiIgnore
    @Controller
    @RequestMapping(REQ_PATH)
    public static class HumanSkillController extends BaseController {
        @Autowired
        IHumanSkillFactory humanKnoHowFactory;

        @GetMapping("/image/001")
        @ResponseBody
        public Object image() {
            HumanSkill skill = humanKnoHowFactory.create();
            getSession().setAttribute(KEY, skill);
            return skill;
        }


        @Bean
        public IHumanSkillFactory getHumanKnoHowFactory() {
            return new IHumanSkillFactory() {
                @Override
                public HumanSkill create() {
                    return new ImageSkill();
                }
            };
        }
    }


    public static class HumanVerifyFilter extends OncePerRequestFilter {

        private AuthenticationFailureHandler failureHandler;

        public HumanVerifyFilter(AuthenticationFailureHandler failureHandler) {
            this.failureHandler = failureHandler;
        }

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

            if (!Objects.equals(request.getRequestURI(), LOGIN_URI) || !Objects.equals(request.getMethod(), "POST")) {
                filterChain.doFilter(request, response);
                return;
            }
            HttpSession session = request.getSession();
            HumanSkill skill = (HumanSkill) session.getAttribute(KEY);
            String val = request.getParameter(PARAM);
            try {
                Objects.requireNonNull(skill, "非法登录");
                Objects.requireNonNull(val, "验证码不能为空");
                session.removeAttribute(KEY);
                if (!skill.isHuman(val)) {
                    throw new NotHumanException(skill.getTips());
                }
                filterChain.doFilter(request, response);
            } catch (NullPointerException | NotHumanException e) {
                failureHandler.onAuthenticationFailure(request, response, new LoginException(e.getMessage()));
            }

        }
    }
}